package com.luhuiguo.cms.client.presenter;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.AppConstants;
import com.luhuiguo.cms.client.AppMessages;
import com.luhuiguo.cms.shared.event.FlashEvent;
import com.luhuiguo.cms.shared.event.FlashEventHandler;
import com.luhuiguo.cms.shared.event.LoginEvent;
import com.luhuiguo.cms.shared.event.LoginEventHandler;
import com.luhuiguo.cms.shared.model.UserModel;
import com.luhuiguo.cms.shared.rpc.GetCurrentUser;
import com.luhuiguo.cms.shared.rpc.GetCurrentUserResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetContainerDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetContainerPresenter;
import com.luhuiguo.gwt.security.shared.event.AccessDeniedEvent;
import com.luhuiguo.gwt.security.shared.event.AccessDeniedEventHandler;

public class AppPresenter extends WidgetContainerPresenter<AppPresenter.Display> {

    public interface Display extends WidgetContainerDisplay {

        void showMessage(String message, int millisecs);

    }

    private UserModel user;

    private AppConstants constants;

    @SuppressWarnings("unused")
    private AppMessages messages;

    private DispatcherAsync dispatcher;

    @SuppressWarnings("unused")
    private HeaderPresenter headerPresenter;

    @SuppressWarnings("unused")
    private FooterPresenter footerPresenter;

    @SuppressWarnings("unused")
    private NavigationPresenter navigationPresenter;

    @SuppressWarnings("unused")
    private MainPresenter mainPresenter;

    @Inject
    public AppPresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher, AppConstants constants,
            AppMessages messages, HeaderPresenter headerPresenter, FooterPresenter footerPresenter,
            NavigationPresenter navigationPresenter, MainPresenter mainPresenter) {

        super(display, eventBus, headerPresenter, footerPresenter, navigationPresenter, mainPresenter);

        this.dispatcher = dispatcher;

        this.constants = constants;
        this.messages = messages;

        this.headerPresenter = headerPresenter;
        this.footerPresenter = footerPresenter;
        this.navigationPresenter = navigationPresenter;
        this.mainPresenter = mainPresenter;

        GWT.log("AppPresenter created");
    }

    @Override
    protected void onBind() {
        GWT.log("AppPresenter onBind");
        super.onBind();

        registerHandler(eventBus.addHandler(LoginEvent.TYPE, new LoginEventHandler() {

            public void onLogin(LoginEvent event) {
                user = event.getUser();
                // showMain(user);
                display.showMessage(constants.welcome(), 3000);
            }
        }));

        registerHandler(eventBus.addHandler(AccessDeniedEvent.TYPE, new AccessDeniedEventHandler() {
            public void onAccessDenied(AccessDeniedEvent event) {
                redirect(constants.loginUrl());
            }

        }));

        registerHandler(eventBus.addHandler(FlashEvent.TYPE, new FlashEventHandler() {
            public void onFlash(FlashEvent event) {
                display.showMessage(event.getMessage(), event.getMillisec());
            }

        }));
        checkUser();
    }

    // private void showMain(UserModel user) {
    // mainPresenter.revealDisplay(user);
    // }

    private void checkUser() {

        dispatcher.execute(new GetCurrentUser(), new AsyncCallback<GetCurrentUserResult>() {
            public void onFailure(Throwable caught) {
                redirect(constants.loginUrl());
            }

            public void onSuccess(GetCurrentUserResult result) {
                eventBus.fireEvent(new LoginEvent(result.get()));
            }
        });
    }

    // redirect the browser to the given url
    public static native void redirect(String url)/*-{
        $wnd.location = url;
    }-*/;

}
